
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * The class provides functionalities for file I/O
 *
 */
public class BinaryFileManager extends FileManager {

    private final static String END_OF_FILE_MARKER = "END_OF_FILE_MARKER";

    /**
     * Constructs a new BinaryFileManager object 
     *
     * @param fileName - the name of the file to operate on
     */
    public BinaryFileManager(String fileName) {
        super(fileName);
    }

    /**
     * Write the ArrayList of departments and employees to the Binary file departments.txt and employees.txt
     *
     * @param objects - the objects to save
     */
    public void saveData(Collection objects) throws Exception  
    {
        FileOutputStream aFileOutputStream = null;
        ObjectOutputStream anObjectOutputStream = null;

        try {
            aFileOutputStream = new FileOutputStream(this.getFile());
            anObjectOutputStream = new ObjectOutputStream(aFileOutputStream);
            for (Object object : objects) 
                 anObjectOutputStream.writeObject(object);
            
            anObjectOutputStream.writeObject(END_OF_FILE_MARKER);
        } 
        finally 
        {
            try {
                if (aFileOutputStream != null) 
                    aFileOutputStream.close();
            } 
            catch (Exception e) { }
            
            try {
                if (anObjectOutputStream != null) {
                    anObjectOutputStream.close();
                }
            } catch (Exception e) { }
        }
    }


    /**
     * Retrieve data from the Binary file and return it as an object
     *
     * @return ArrayList of departments or employees
     */
    public List loadData() throws Exception  
    {
        FileInputStream aFileInputStream = null;
        ObjectInputStream anObjectInputStream = null;
        List objects = null;
        Object object = null;

        try {
            File aFile = this.getFile();
            if (aFile.exists()) 
            {
                aFileInputStream = new FileInputStream(aFile);
                anObjectInputStream = new ObjectInputStream(aFileInputStream);
                objects = new ArrayList();
                boolean hasMoreObject = true;

                while (hasMoreObject) 
                {
                    object = anObjectInputStream.readObject();
                    if (object != null && object instanceof String && ((String)object).equals(END_OF_FILE_MARKER)) 
                                hasMoreObject = false;
                    else
                        objects.add(object);
                } 

                if (objects.size() == 0) 
                    throw new Exception(); 
             } 
            else {
                createFile();
            }
            return objects;
        } 
        finally 
        {
            try {
                if (aFileInputStream != null) 
                    aFileInputStream.close();
            } catch (Exception e) { }

            try {
                if (anObjectInputStream != null) 
                    anObjectInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}
